package com.wandousoushu.jiusen.ui.book.read

import android.app.Application
import android.content.Intent
import com.wandousoushu.jiusen.MyApplication
import com.wandousoushu.jiusen.R
import com.wandousoushu.jiusen.base.BaseViewModel
import com.wandousoushu.jiusen.booksource.bean.BookChapter
import com.wandousoushu.jiusen.booksource.data.entities.Book
import com.wandousoushu.jiusen.booksource.data.entities.ReadBook
import com.wandousoushu.jiusen.booksource.model.BookChapterManager
import com.wandousoushu.jiusen.booksource.model.BookManager
import com.wandousoushu.jiusen.booksource.model.BookSourceManager
import com.wandousoushu.jiusen.booksource.model.WebBook
import com.wandousoushu.jiusen.help.AppConfig
import com.wandousoushu.jiusen.help.BookHelp
import com.wandousoushu.jiusen.help.IntentDataHelp
import com.wandousoushu.jiusen.service.BaseReadAloudService
import com.wandousoushu.jiusen.service.ReadAloud
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.withContext

class ReadBookViewModel(application: Application) : BaseViewModel(application) {

    var isInitFinish = false

    fun initData(intent: Intent) {
        execute {
            ReadBook.inBookshelf = intent.getBooleanExtra("inBookshelf", true)
            IntentDataHelp.getData<Book>(intent.getStringExtra("key"))?.let {
                initBook(it)
            } ?: intent.getStringExtra("bookUrl")?.let {
                BookManager.GetInstance().GetBookByUrl(it)?.let { book ->
                    initBook(book)
                }
            } ?: BookManager.GetInstance().GetFirstBook()?.let {
                initBook(it)
            }
        }.onFinally {
            if (ReadBook.inBookshelf) {
                ReadBook.saveRead()
            }
        }
    }

    private fun initBook(book: Book) {
        if (ReadBook.book?.bookUrl != book.bookUrl) {
            ReadBook.resetData(book)
            if (!book.isLocalBook() && ReadBook.webBook == null) {
                //autoChangeSource(book.name, book.author)
                return
            }
            isInitFinish = true
            ReadBook.chapterSize = BookChapterManager.GetInstance().GetBookChapterCountByUrl(book.bookUrl)
            if (ReadBook.chapterSize == 0) {
                if (book.tocUrl.isEmpty()) {
                    loadBookInfo(book)
                } else {
                    loadChapterList(book)
                }
            } else {
                if (ReadBook.durChapterIndex > ReadBook.chapterSize - 1) {
                    ReadBook.durChapterIndex = ReadBook.chapterSize - 1
                }
                ReadBook.loadContent(resetPageOffset = true)
            }
        } else {
            isInitFinish = true
            ReadBook.book!!.group = book.group
            ReadBook.titleDate.postValue(book.name)
            ReadBook.upWebBook(book)
            if (!book.isLocalBook() && ReadBook.webBook == null) {
                //autoChangeSource(book.name, book.author)
                return
            }
            ReadBook.chapterSize = BookChapterManager.GetInstance().GetBookChapterCountByUrl(book.bookUrl)
            if (ReadBook.chapterSize == 0) {
                if (book.tocUrl.isEmpty()) {
                    loadBookInfo(book)
                } else {
                    loadChapterList(book)
                }
            } else {
                if (ReadBook.curTextChapter != null) {
                    ReadBook.callBack?.upContent(resetPageOffset = false)
                }
            }
        }
    }

    private fun loadBookInfo(
        book: Book,
        changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null
    ) {
        execute {
            if (book.isLocalBook()) {
                loadChapterList(book, changeDruChapterIndex)
            } else {
                ReadBook.webBook?.getBookInfo(book, this)
                    ?.onSuccess {
                        loadChapterList(book, changeDruChapterIndex)
                    }
            }
        }
    }

    fun loadChapterList(
        book: Book,
        changeDruChapterIndex: ((chapters: List<BookChapter>) -> Unit)? = null
    ) {
        execute {
//            if (book.isLocalBook()) {
//                LocalBook.getChapterList(book).let {
//                    App.db.bookChapterDao().delByBook(book.bookUrl)
//                    App.db.bookChapterDao().insert(*it.toTypedArray())
//                    App.db.bookDao().update(book)
//                    ReadBook.chapterSize = it.size
//                    if (it.isEmpty()) {
//                        ReadBook.upMsg(context.getString(R.string.error_load_toc))
//                    } else {
//                        ReadBook.upMsg(null)
//                        ReadBook.loadContent(resetPageOffset = true)
//                    }
//                }
//            } else {
//                ReadBook.webBook?.getChapterList(book, this)
//                    ?.onSuccess(IO) { cList ->
//                        if (cList.isNotEmpty()) {
//                            if (changeDruChapterIndex == null) {
//                                App.db.bookChapterDao().insert(*cList.toTypedArray())
//                                App.db.bookDao().update(book)
//                                ReadBook.chapterSize = cList.size
//                                ReadBook.upMsg(null)
//                                ReadBook.loadContent(resetPageOffset = true)
//                            } else {
//                                changeDruChapterIndex(cList)
//                            }
//                        } else {
//                            ReadBook.upMsg(context.getString(R.string.error_load_toc))
//                        }
//                    }?.onError {
//                        ReadBook.upMsg(context.getString(R.string.error_load_toc))
//                    }
//            }
            ReadBook.webBook?.getChapterList(book, this)
                    ?.onSuccess(IO) { cList ->
                        if (cList.isNotEmpty()) {
                            if (changeDruChapterIndex == null) {
//                                App.db.bookChapterDao().insert(*cList.toTypedArray())
//                                App.db.bookDao().update(book)
                                BookChapterManager.GetInstance().AddBookChapters(cList)

                                ReadBook.chapterSize = cList.size
                                ReadBook.upMsg(null)
                                ReadBook.loadContent(resetPageOffset = true)
                            } else {
                                changeDruChapterIndex(cList)
                            }
                        } else {
                            ReadBook.upMsg(context.getString(R.string.error_load_toc))
                        }
                    }?.onError {
                        ReadBook.upMsg(context.getString(R.string.error_load_toc))
                    }
        }.onError {
            ReadBook.upMsg("LoadTocError:${it.localizedMessage}")
        }
    }

    fun changeTo(newBook: Book) {
        execute {
            var mOldBook=ReadBook.book
            ReadBook.upMsg(null)
            ReadBook.book?.changeTo(newBook)
            ReadBook.prevTextChapter = null
            ReadBook.curTextChapter = null
            ReadBook.nextTextChapter = null
            withContext(Main) {
                ReadBook.callBack?.upContent()
            }
            ReadBook.book = newBook
            BookSourceManager.GetInstance().getBookSource(newBook.origin)?.let {
                ReadBook.webBook = WebBook(it)
            }
            if (newBook.tocUrl.isEmpty()) {
                loadBookInfo(newBook) {
                    if (mOldBook != null) {
                        upChangeDurChapterIndex(mOldBook,newBook, it)
                    }
                }
            } else {
                loadChapterList(newBook) {
                    if (mOldBook != null) {
                        upChangeDurChapterIndex(mOldBook,newBook, it)
                    }
                }
            }
        }
    }

//    private fun autoChangeSource(name: String, author: String) {
//        if (!AppConfig.autoChangeSource) return
//        execute {
//            MyApplication.instance.getBookSourceList().forEach { source ->
//                try {
//                    val searchBooks = WebBook(source).searchBookSuspend(this, name)
//                    searchBooks.getOrNull(0)?.let {
//                        if (it.name == name && (it.author == author || author == "")) {
//                            changeTo(it.toBook())
//                            return@forEach
//                        }
//                    }
//                } catch (e: Exception) {
//                    //nothing
//                }
//            }
//        }.onStart {
//            ReadBook.upMsg(context.getString(R.string.source_auto_changing))
//        }.onFinally {
//            ReadBook.upMsg(null)
//        }
//    }

    private fun upChangeDurChapterIndex(oldbook: Book,newbook: Book, chapters: List<BookChapter>) {
        execute {
            ReadBook.durChapterIndex = BookHelp.getDurChapterIndexByChapterTitle(
                    newbook.durChapterTitle,
                    newbook.durChapterIndex,
                chapters
            )
            newbook.durChapterIndex = ReadBook.durChapterIndex
            newbook.durChapterTitle = chapters[ReadBook.durChapterIndex].title
            BookManager.GetInstance().UpdateChangeOriginBook(oldbook,newbook)
//            App.db.bookDao().update(book)
//            App.db.bookChapterDao().insert(*chapters.toTypedArray())
            BookChapterManager.GetInstance().AddBookChapters(chapters);
            ReadBook.chapterSize = chapters.size
            ReadBook.loadContent(resetPageOffset = true)
        }
    }

    fun openChapter(index: Int, pageIndex: Int = 0) {
        ReadBook.prevTextChapter = null
        ReadBook.curTextChapter = null
        ReadBook.nextTextChapter = null
        ReadBook.callBack?.upContent()
        if (index != ReadBook.durChapterIndex) {
            ReadBook.durChapterIndex = index
            ReadBook.durPageIndex = pageIndex
        }
        ReadBook.saveRead()
        ReadBook.loadContent(resetPageOffset = true)
    }

    fun removeFromBookshelf(success: (() -> Unit)?) {
        execute {
            ReadBook.book?.deleteShelf()
        }.onSuccess {
            success?.invoke()
        }
    }

    fun removeFromBookMark(success: (() -> Unit)?) {
        execute {
            ReadBook.book?.deleteMark()
        }.onSuccess {
            success?.invoke()
        }
    }

    fun upBookSource() {
        execute {
            ReadBook.book?.let { book ->
                BookSourceManager.GetInstance().getBookSource(book.bookUrl)?.let {
                    ReadBook.webBook = WebBook(it)
                }
            }
        }
    }

    fun refreshContent(book: Book) {
        execute {
            //App.db.bookChapterDao().getChapter(book.bookUrl, ReadBook.durChapterIndex)
            BookChapterManager.GetInstance().GetBookChapterByUrl(book.bookUrl)
                ?.let { chapter ->
                    BookHelp.delContent(book, chapter)
                    ReadBook.loadContent(ReadBook.durChapterIndex, resetPageOffset = false)
                }
        }
    }

    override fun onCleared() {
        super.onCleared()
        if (BaseReadAloudService.pause) {
            ReadAloud.stop(context)
        }
    }

}